package com.ruoyi.mobile.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.mobile.domain.SysUserAddressEntity;
import com.ruoyi.mobile.domain.SysUserEntity;
import com.ruoyi.mobile.mapper.ISysUserAddressMapper;
import com.ruoyi.mobile.mapper.ISysUserMapper;
import com.ruoyi.mobile.service.AuthService;
import com.ruoyi.mobile.service.VerifyCodeService;
import com.ruoyi.mobile.utils.*;
import com.ruoyi.system.api.req.LoginReq;
import com.ruoyi.system.api.req.SysUserReq;
import com.ruoyi.system.api.resp.LoginResp;
import com.ruoyi.system.api.resp.SysUserAddressResp;
import com.ruoyi.system.api.resp.SysUserResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl extends ServiceImpl<ISysUserMapper, SysUserEntity> implements AuthService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisService redisService;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private ISysUserAddressMapper sysUserAddressMapper;

    @Override
    public NftResponse<SysUserResp> initAppUser(LoginReq loginReq) {
        //获取到header中的东西
        if(loginReq.getUserName() == null || "".equals(loginReq.getUserName())){
            return new NftResponse<>(ResponseConstants.ERROR_CODE,"参数不完整",null);
        }
        if(loginReq.getPhoneCode() == null || "".equals(loginReq.getPhoneCode())){
            return new NftResponse(ResponseConstants.ERROR_CODE,"请输入用户名或者验证码",null);
        }
        Object failCountObject = redisTemplate.opsForValue().get("failCount:"+loginReq.getUserName());
        Integer failCount = 0;
        if(failCountObject != null){
            failCount = Integer.valueOf(failCountObject.toString());
            if(failCount >= 5){
                return new NftResponse<>(ResponseConstants.ERROR_CODE,"重试次数达5次，请稍后重试",null);
            }
        }
        Boolean verifyCodeResult = verifyCodeService.verifyCode(loginReq.getUserName(), loginReq.getPhoneCode());
        if(!verifyCodeResult){
            redisTemplate.opsForValue().set("failCount:"+ loginReq.getUserName(), failCount == null ? 1 : (failCount + 1),10*60*1000, TimeUnit.MILLISECONDS);
            return new NftResponse<>(ResponseConstants.ERROR_CODE,"验证码不正确",null);
        }
        SysUserReq sysUserReq = new SysUserReq();
        sysUserReq.setUserName(loginReq.getUserName());
        sysUserReq.setAppId(loginReq.getAppid());
        sysUserReq.setYwType(loginReq.getYwtype());
        SysUserResp sysUserResp = this.getUserInfo(sysUserReq);
        if(sysUserResp != null && "1".equals(sysUserResp.getStatus())){
            return new NftResponse(ResponseConstants.ERROR_CODE,"您的账号受限，请联系管理员",null);
        }
        if(sysUserResp == null){
            //用户注册
            Long inviteId = loginReq.getInviteId();
            if (null!=inviteId&&inviteId>0) {
                sysUserReq.setInviteId(inviteId);
                SysUserEntity invite = this.baseMapper.selectById(inviteId);
                if (null!=invite&&null!=invite.getInviteId()) {
                    sysUserReq.setPinviteId(invite.getInviteId());
                }
            }
            NftResponse registerResult = userMinRegister(sysUserReq);
            if (registerResult.getCode().equals(ResponseConstants.ERROR_CODE)) {
                return new NftResponse(registerResult.getCode(),registerResult.getMsg(),null);
            }
            SysUserEntity userAppEntity = (SysUserEntity) registerResult.getData();
            sysUserResp = this.getUserAppInfo(userAppEntity.getPhonenumber());
        }
        if(loginReq.getUserId() != null && loginReq.getUserId() > 0){
            Object redisLoginInfoObj = redisTemplate.opsForValue().get("userinfo-app:"+loginReq.getUserId());
            if(redisLoginInfoObj != null){
                LoginResp redisLoginInfo = JSONUtil.toBean(redisLoginInfoObj.toString(), LoginResp.class);
                if(redisLoginInfo.getUserName().equals(loginReq.getUserName())){
                    String token = JwtUtils.token(loginReq.getUserName(),String.valueOf(sysUserResp.getUserId()));
                    redisLoginInfo.setToken(token);
                    redisTemplate.opsForValue().set("userinfo-app:"+redisLoginInfo.getUserId(), JSONUtil.toJsonStr(redisLoginInfo), 10 * 24 * 60 * 60 * 1000,TimeUnit.MILLISECONDS);
                    return new NftResponse(ResponseConstants.SUCCESS_CODE,"登录成功",redisLoginInfo);
                }
            }
        }
        String token = JwtUtils.token(loginReq.getUserName(),String.valueOf(sysUserResp.getUserId()));
        sysUserResp.setToken(token);
        redisTemplate.opsForValue().set("userinfo-app:"+sysUserResp.getUserId(), JSONUtil.toJsonStr(sysUserResp), 10 * 24 * 60 * 60 * 1000,TimeUnit.MILLISECONDS);
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"登录成功", sysUserResp);
    }

    private SysUserResp getUserAppInfo(String phone) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), phone);
        SysUserEntity userAppEntity = this.baseMapper.selectOne(wrapper);
        if(userAppEntity == null){
            return null;
        }
        SysUserResp rtn = BeanUtil.copyProperties(userAppEntity, SysUserResp.class);
        QueryWrapper<SysUserAddressEntity> wrapperAdr = new QueryWrapper<>();
        wrapperAdr.eq(QueryUtil.camelToUnderline("userId"), userAppEntity.getUserId());
        wrapperAdr.orderByDesc("isfirst");
        List<SysUserAddressEntity> listAdr = this.sysUserAddressMapper.selectList(wrapperAdr);
        List<SysUserAddressResp> listRespAdr = BeanUtil.copyToList(listAdr, SysUserAddressResp.class);
        rtn.setAllAddress(listRespAdr);
        return rtn;
    }

    @Override
    public NftResponse<SysUserResp> login(LoginReq loginReq) {
        SysUserResp sysUserResp = this.getUserAppInfo(loginReq.getUserName());
        if (SecurityUtils.matchesPassword(loginReq.getPassword(), sysUserResp.getPassword())) {
            String token = JwtUtils.token(loginReq.getUserName(),String.valueOf(sysUserResp.getId()));
            sysUserResp.setToken(token);
            redisTemplate.opsForValue().set("userinfo-app:"+sysUserResp.getUserId(), JSONUtil.toJsonStr(sysUserResp), 10 * 24 * 60 * 60 * 1000,TimeUnit.MILLISECONDS);
            return new NftResponse(ResponseConstants.SUCCESS_CODE,"登录成功", sysUserResp);
        }else {
            return new NftResponse(ResponseConstants.ERROR_CODE,"登录失败", null);
        }
    }

    @Override
    public NftResponse<Boolean> logout(Integer userId) {
        SysUserEntity sysUserEntity = this.baseMapper.selectById(userId);
        if(sysUserEntity == null){
            return new NftResponse<>(ResponseConstants.ERROR_CODE,"查无此人",false);
        }
        redisTemplate.delete("userinfo-app:"+userId);
        return new NftResponse<>(ResponseConstants.SUCCESS_CODE,"退出登录成功",true);
    }

    public SysUserResp getUserInfo(SysUserReq sysUserReq) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), sysUserReq.getUserName());
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"),"0");
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        List<SysUserEntity> users = this.baseMapper.selectList(wrapper);
        if (null!=users&&users.size()>0) {
            SysUserResp sysUserResp = null;
            SysUserEntity sysUserEntity = users.get(0);
            if ("2".equals(sysUserReq.getYwType())&&null==sysUserEntity.getAppIdf()) {
                sysUserEntity.setAppIdf(sysUserReq.getAppId());
                sysUserEntity.setYwType(sysUserEntity.getYwType()+","+sysUserReq.getYwType());
                this.baseMapper.updateById(sysUserEntity);
            }else if ("3".equals(sysUserReq.getYwType())&&null==sysUserEntity.getAppId()) {
                sysUserEntity.setAppId(sysUserReq.getAppId());
                sysUserEntity.setYwType(sysUserEntity.getYwType()+","+sysUserReq.getYwType());
                this.baseMapper.updateById(sysUserEntity);
            }
            sysUserResp = BeanUtil.copyProperties(sysUserEntity, SysUserResp.class);
            return sysUserResp;
        }else {
            return null;
        }
    }

    public NftResponse userMinRegister(SysUserReq sysUserReq) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), sysUserReq.getUserName());
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"),"0");
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        Long userCount = this.baseMapper.selectCount(wrapper);
        if(userCount > 0) {
            List<SysUserEntity> userList = this.baseMapper.selectList(wrapper);
            SysUserEntity user = userList.get(0);
            if ("1".equals(sysUserReq.getYwType())&&null==user.getAppIdm()) {
                user.setAppIdm(sysUserReq.getAppId());
                user.setYwType(user.getYwType()+","+sysUserReq.getYwType());
                this.baseMapper.updateById(user);
                return new NftResponse(ResponseConstants.SUCCESS_CODE, "注册成功", user);
            }else if ("2".equals(sysUserReq.getYwType())&&null==user.getAppIdf()) {
                user.setAppIdf(sysUserReq.getAppId());
                user.setYwType(user.getYwType()+","+sysUserReq.getYwType());
                this.baseMapper.updateById(user);
                return new NftResponse(ResponseConstants.SUCCESS_CODE, "注册成功", user);
            }else if ("3".equals(sysUserReq.getYwType())&&null==user.getAppId()) {
                user.setAppId(sysUserReq.getAppId());
                user.setYwType(user.getYwType()+","+sysUserReq.getYwType());
                this.baseMapper.updateById(user);
                return new NftResponse(ResponseConstants.SUCCESS_CODE, "注册成功", user);
            }else {
                return new NftResponse(ResponseConstants.ERROR_CODE, "您的手机号已经注册过了", null);
            }
        }
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setPhonenumber(sysUserReq.getUserName());
        sysUserEntity.setUserName("获取姓名");
        sysUserEntity.setCreateTime(DateUtils.getNowDate());
        sysUserEntity.setInviteId(sysUserReq.getInviteId());
        sysUserEntity.setPinviteId(sysUserReq.getPinviteId());
        sysUserEntity.setYwType(sysUserReq.getYwType());
        if ("1".equals(sysUserReq.getYwType())) {
            sysUserEntity.setAppIdm(sysUserReq.getAppId());
        }else if ("2".equals(sysUserReq.getYwType())) {
            sysUserEntity.setAppIdf(sysUserReq.getAppId());
        }else if ("3".equals(sysUserReq.getYwType())) {
            sysUserEntity.setAppId(sysUserReq.getAppId());
        }
        Integer result = this.baseMapper.insert(sysUserEntity);
        if(result <= 0){
            return new NftResponse(ResponseConstants.ERROR_CODE,"注册失败",null);
        }
        return new NftResponse(ResponseConstants.SUCCESS_CODE,"注册成功", sysUserEntity);
    }

    @Override
    public NftResponse<Boolean> putUsername(Long userId, String userName) {
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setUserId(userId);
        sysUserEntity.setUserName(userName);
        int rtn = this.baseMapper.updateById(sysUserEntity);
        if (rtn>0) {
            return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "修改成功", true);
        }else {
            return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "修改失败", false);
        }
    }

    @Override
    public NftResponse<Boolean> putSex(Long userId, String sex) {
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setUserId(userId);
        sysUserEntity.setSex(sex);
        int rtn = this.baseMapper.updateById(sysUserEntity);
        if (rtn>0) {
            return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "修改成功", true);
        }else {
            return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "修改失败", false);
        }
    }

    @Override
    public String putAvatar(HttpServletRequest request, MultipartFile file) {
        String fileBase64 = "";
        try {
            fileBase64 = Base64Util.getInstance().encode(file.getBytes());
            SysUserEntity sysUserEntity = new SysUserEntity();
            sysUserEntity.setUserId(Long.valueOf(request.getParameter("userId")));
            sysUserEntity.setAvatar(fileBase64);
            this.baseMapper.updateById(sysUserEntity);
        }catch (IOException ioe) {}
        return fileBase64;
    }

    @Override
    public Boolean putOpenId(String appid, String phonenumber, String openId, Long inviteId) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("phonenumber"), phonenumber);
        List<SysUserEntity> users = this.baseMapper.selectList(wrapper);
        if (null==users||users.size()<=0) {
            SysUserReq sysUserReq = new SysUserReq();
            sysUserReq.setUserName(phonenumber);
            sysUserReq.setYwType("1");
            sysUserReq.setAppIdm(appid);
            if (inviteId>0) {
                sysUserReq.setInviteId(inviteId);
                SysUserEntity invite = this.baseMapper.selectById(inviteId);
                if (null!=invite&&null!=invite.getInviteId()) {
                    sysUserReq.setPinviteId(invite.getInviteId());
                }
            }
            NftResponse registerResult = this.userMinRegister(sysUserReq);
            if (null!=registerResult) {
                SysUserEntity userAppEntity = (SysUserEntity)registerResult.getData();
                userAppEntity.setOpenId(openId);
                this.baseMapper.updateById(userAppEntity);
            }
            return true;
        }else {
            SysUserEntity user = users.get(0);
            if (!openId.equals(user.getOpenId())) {
                this.baseMapper.updateUserOpenIdByPhone(phonenumber, openId, appid);
            }
            return true;
        }
    }

    @Override
    public NftResponse<SysUserResp> getUserInfo(String openId) {
        QueryWrapper<SysUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(QueryUtil.camelToUnderline("status"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("delFlag"), "0");
        wrapper.eq(QueryUtil.camelToUnderline("openId"), openId);
        List<SysUserEntity> users = this.baseMapper.selectList(wrapper);
        if (users==null||users.size()<=0) {
            return new NftResponse<>(ResponseConstants.ERROR_CODE, "查无此人", null);
        }
        SysUserResp userAppResp = BeanUtil.copyProperties(users.get(0), SysUserResp.class);
        SysUserResp rtn = this.baseMapper.getUserInfo(users.get(0).getUserId());
        if (null!=rtn&&null!=rtn.getUserId()) {
            userAppResp.setIsManager(true);
        }else {
            userAppResp.setIsManager(false);
        }
        QueryWrapper<SysUserAddressEntity> wrapperAdr = new QueryWrapper<>();
        wrapperAdr.eq(QueryUtil.camelToUnderline("userId"), users.get(0).getUserId());
        wrapperAdr.orderByDesc("isfirst");
        List<SysUserAddressEntity> listAdr = this.sysUserAddressMapper.selectList(wrapperAdr);
        List<SysUserAddressResp> listRespAdr = BeanUtil.copyToList(listAdr, SysUserAddressResp.class);
        userAppResp.setAllAddress(listRespAdr);
        return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "查询成功", userAppResp);
    }
}
